package com.sunday.gateway.security.authentication;

import com.sunday.common.core.enums.ErrorCodeEnum;
import com.sunday.common.core.remoting.rest.response.RestResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.server.authentication.OAuth2LoginAuthenticationWebFilter;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Deprecated
@Slf4j
@RequiredArgsConstructor
public class JsonServerAuthenticationSuccessHandler implements ServerAuthenticationSuccessHandler, JsonBaseAuthenticationHandler {

    private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;

    /**
     * 应用程序身份验证成功时调用
     */
    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        ServerWebExchange exchange = webFilterExchange.getExchange();
        ServerHttpResponse response = exchange.getResponse();

        log.info("登录成功, {} ", authentication.getPrincipal());

        if (authentication instanceof OAuth2AuthenticationToken oauth2Token) {
            String clientRegistrationId = oauth2Token.getAuthorizedClientRegistrationId();

            /**
             * 程序重启更新拉取信息
             * @see AuthenticationWebFilter#filter(ServerWebExchange, WebFilterChain)
             * @see AuthenticationWebFilter#authenticate(ServerWebExchange, WebFilterChain, Authentication)
             * @see OAuth2LoginAuthenticationWebFilter#onAuthenticationSuccess(Authentication, WebFilterExchange)
             *
             * 加载流程
             * @see AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository#loadAuthorizedClient(String, Authentication, ServerWebExchange)
             * @see InMemoryReactiveOAuth2AuthorizedClientService#loadAuthorizedClient(String, String)
             */
            // 使用 flatMap 避免阻塞操作
            return authorizedClientRepository.loadAuthorizedClient(clientRegistrationId, oauth2Token, exchange)
                    .flatMap(client -> {
                        if (client != null) {
                            String accessToken = client.getAccessToken().getTokenValue();
                            String refreshToken = client.getRefreshToken() != null ? client.getRefreshToken().getTokenValue() : null;
                            response.getHeaders().add("Authorization", STR."Bearer \{accessToken}");
                            if (refreshToken != null) {
                                response.getHeaders().add("Refresh-Token", refreshToken);
                            }
                        }
                        return writeJson(response, RestResponse.ok());
                    })
                    .then(
                            // 使用后清空，因使用得是jwt，所以无需保存
                            authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, oauth2Token, exchange)
                    )
                    ;
        }
        // 登录成功后可以放入一些参数到session中
        return writeJson(response, RestResponse.error(ErrorCodeEnum.A0_200));
    }


}